/*
	The original MD2 code was modified to calculate vertex normals and interpolate
	normals for animation.  Original info below:



 *  MD2.h
 *  MD2 File Loading
 *
 *  Created by Seth Willits on 9/11/04.
 *  Copyright 2004 Freak Software. All rights reserved.
 *
 *  Small portions of this file are from the MD2 file loading routines
 *  found in Chapter 18 of OpenGL Game Programming by Kevin Hawkins
 *  and Dave Astle.
 */
 
 
 
#ifndef __MD2__
#define __MD2__

#include <string>//.h
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include "Texture.h"

#include <vector>
#include "Vector3.h"




/*	Frame#  Action
*	----------------
*	0-39    idle
*	40-46   running
*	47-60   getting shot but not falling (back bending)
*	61-66   getting shot in shoulder
*	67-73   jumping
*	74-95   idle
*	96-112  getting shot and falling down
*	113-122 idle
*	123-135 idle
*	136-154 crouch
*	155-161 crouch crawl
*	162-169 crouch adjust weapon (idle)
*	170-177 kneeling dying
*	178-185 falling back dying
*	186-190 falling forward dying
*	191-197 falling back slow dying 
*/


/////////////////////////////////////////////////////////////////////////////////
//
//							Vector Functionality
//
/////////////////////////////////////////////////////////////////////////////////

// A single vertex
typedef struct
{
   float point[3];
} MD2Vector;

MD2Vector operator-(MD2Vector a, MD2Vector b);
MD2Vector operator*(float f, MD2Vector b);
MD2Vector operator/(MD2Vector a, MD2Vector b);
MD2Vector operator+(MD2Vector a, MD2Vector b);





/////////////////////////////////////////////////////////////////////////////////
//
//							MD2 Model Functionality
//
/////////////////////////////////////////////////////////////////////////////////

// texture coordinate
typedef struct
{
	float s;
	float t;
} MD2TextureCoord;

// texture coordinate index
typedef struct
{
	short s;
	short t;
} MD2TexCoordIndex;

// info for a single frame point
typedef struct
{
	unsigned char v[3];
	unsigned char normalIndex;	// not used
} MD2FramePoint;

// information for a single frame
typedef struct
{
	float scale[3];
	float translate[3];
	char name[16];
	MD2FramePoint * fp; //fp[1];
} MD2Frame;

// data for a single triangle
typedef struct
{
	unsigned short meshIndex[3];		// vertex indices
	unsigned short stIndex[3];		// texture coordinate indices
} MD2Mesh;


typedef struct
{
	int ident;			// identifies as MD2 file "IDP2"
	int version;		// mine is 8
	int skinwidth;		// width of texture
	int skinheight;		// height of texture
	int framesize;		// number of bytes per frame
	int NumSkins;		// number of textures
	int NumVertices;	// number of points
	int NumTexCoords;	// number of texture coordinates
	int NumTriangles;	// number of triangles
	int NumGLCmds;		// number of OpenGL commands
	int NumFrames;		// total number of frames
	int offsetSkins;	// offset to skin names (64 bytes each)
	int offsetST;			// offset of texture s-t values
	int offsetTriangles;	// offset of triangle mesh
	int offsetFrames;		// offset of frame data (points)
	int offsetGLCmds;		// type of OpenGL commands to use
	int offsetEndOfFile;	// end of file
} MD2ModelHeader;


class MD2Model
{
	private:
		int NumFrames;				// number of model frames
		
		int NumTriangles;			// number of triangles
		int NumTexCoords;			// number of texture coordinates
		int FrameSize;				// size of each frame in bytes
		MD2Mesh * TrianglesIndex;			// triangle list
		MD2TextureCoord * TextureCoords;	// texture coordinate list
		
		MD2Texture * ModelTex;				// texture data
		MD2Vector * normalList;

		void SetupSkin(MD2Texture *thisTexture);

		// File Reading
		short ReadShort(FILE *filePtr);
		int ReadInt(FILE *filePtr);
		float ReadFloat(FILE *filePtr);
		void ReadHeader(FILE *filePtr, MD2ModelHeader & Header);
		void CalculateNormal(float *p1, float *p2, float *p3);

	public:
		int NumVertices;			// number of vertices
		MD2Vector * VertexList;				// vertex list

		MD2Model();        // constructor
		~MD2Model();       // destructor
		
		// load model and skin/texture at the same time
		bool Load(char *modelFile, char *skinFile);
		
		// render model
		void Draw(int CurrentFrame, int NextFrame, float Interpolation);
};



#endif